﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Kokomo.Mirror.CliMetadata.Signatures;
using System.ComponentModel;

namespace Kokomo.Mirror.CliMetadata.Tables
{
	public class ConstantRow : IMetadataRow
	{
		public byte Type { get; set; }
		public byte TypePadding { get; set; }
		[CodedIndex(CodedIndexType.HasConstant)]
		public CodedIndex Parent { get; set; }
		public BlobRef Value { get; set; }

		public object ToValue(MetadataContainer container)
		{
			byte[] constantData = container.GetBlob(this.Value);
			BitReader reader = new BitReader(constantData);
			//BinaryReader reader = new BinaryReader(new MemoryStream(constantData), Encoding.Unicode);
			SignatureElementType elementType = (SignatureElementType)this.Type;
			object value = null;
			switch (elementType)
			{
				case SignatureElementType.Boolean:
					value = (reader.ReadBoolean());
					break;
				case SignatureElementType.Char:
					value = reader.ReadUtf16Char();
					break;
				case SignatureElementType.SByte:
					value = reader.ReadSByte();
					break;
				case SignatureElementType.Byte:
					value = reader.ReadByte();
					break;
				case SignatureElementType.Int16:
					value = reader.ReadInt16();
					break;
				case SignatureElementType.UInt16:
					value = reader.ReadUInt16();
					break;
				case SignatureElementType.Int32:
					value = reader.ReadInt32();
					break;
				case SignatureElementType.UInt32:
					value = reader.ReadUInt32();
					break;
				case SignatureElementType.Int64:
					value = reader.ReadInt64();
					break;
				case SignatureElementType.UInt64:
					value = reader.ReadUInt64();
					break;
				case SignatureElementType.Class:
					value = null;
					break;
				case SignatureElementType.String:
					value = Encoding.Unicode.GetString(constantData, 0, constantData.Length);
					break;
				default:
					throw new MalformedSignatureException(constantData, 0);
			}

			return value;
		}

		public override string ToString(MetadataContainer container)
		{
			object value = this.ToValue(container);
			if (value == null) return null;
			else return value.ToString();
		}
	}
}
